import 'dart:async';
import 'package:flutter/material.dart';
import 'package:amap_flutter_location/amap_flutter_location.dart';
import 'package:amap_flutter_location/amap_location_option.dart';
import 'package:flutter_application_1/global.dart';
import 'package:flutter_application_1/models/LocationPoi.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:flutter_application_1/api/location.dart' as LocationApi;

class LocationProvider with ChangeNotifier {
  // 定位插件
  late AMapFlutterLocation locationPlugin;
  // 经度
  double? longitude;
  // 纬度
  double? latitude;
  // 省
  String? province;
  // 市
  String city = '北京市';
  // 区
  String? district;
  // 街道
  String? street;
  // 门牌
  String? streetNumber;
  // 详细地址
  String? address;
  // // 附近地点
  List<LocationPoi> aroundPois = [];
  // // 搜索地点
  List<LocationPoi> searchPois = [];
  // 是否拥有定位权限
  bool hasPermission = false;
  // 监听器
  StreamSubscription<Map<String, Object>>? listener;

  // 是否有定位
  bool get hasLocation {
    return this.longitude != null && this.latitude != null;
  }

  Future<bool> init(BuildContext context) async {
    // 实例定位插件
    AMapFlutterLocation.setApiKey(
      Global.MAP_ANDROID_KEY,
      Global.MAP_IOS_KEY,
    );
    this.locationPlugin = AMapFlutterLocation();
    // 请求权限
    return await fetchLocation(context);
  }

  // 设置当前定位
  void setLocation(double longitude, double latitude) {
    this.longitude = longitude;
    this.latitude = latitude;
    notifyListeners();
  }

  // 设置地址
  void setAddress(String address) {
    this.address = address;
    notifyListeners();
  }

  // 设置城市
  void setCity(String city) {
    this.city = city;
    notifyListeners();
  }

  // 清空搜索地点
  void clearSearchPois() {
    this.searchPois = [];
    notifyListeners();
  }

  // 根据经纬度获取定位
  Future<Map<String, dynamic>?> getLocation({
    double? longitude,
    double? latitude,
  }) async {
    // 设置经纬度
    this.longitude = longitude ?? this.longitude;
    this.latitude = latitude ?? this.latitude;
    // 请求
    Map<String, dynamic>? response = await LocationApi.geocodeRegeo(
      longitude: this.longitude!,
      latitude: this.latitude!,
    );

    if (response != null &&
        response['status'] == '1' &&
        response.containsKey('regeocode') &&
        response['regeocode'].containsKey('addressComponent') &&
        response['regeocode']['formatted_address'] is String) {
      Map addressComponent = response['regeocode']['addressComponent'];
      this.province = addressComponent['province'] ?? this.province;
      this.city = addressComponent['city'] ?? this.city;
      this.district = addressComponent['district'] ?? this.district;
      this.streetNumber =
          addressComponent['streetNumber']['number'] ?? this.streetNumber;
      this.address = response['regeocode']['formatted_address'];
      notifyListeners();
      return response;
    }
  }

  // 获取当前定位
  Future<bool> fetchLocation(BuildContext? context) async {
    // 判断权限
    Map<Permission, PermissionStatus> statuses =
        await [Permission.location].request();
    if (statuses[Permission.location] == PermissionStatus.granted) {
      this.hasPermission = true;
      // 监听
      if (listener == null) {
        listener = locationPlugin.onLocationChanged().listen((event) {
          locationPlugin.stopLocation();
          // setLocation(event);
          this.longitude = event['longitude'] as double?;
          this.latitude = event['latitude'] as double?;
          this.province = event['province'] as String?;
          this.city = event['city'] as String;
          this.district = event['district'] as String?;
          this.street = event['street'] as String?;
          this.streetNumber = event['streetNumber'] as String?;
          this.address = event['address'] as String?;

          // 获取当前定位
          this.getLocation().then((value) {
            // 获取定位失败
            if (value == null) {
              notifyListeners();
            }
          });
        });
      }
      // 定位设置
      locationPlugin.setLocationOption(AMapLocationOption(
        onceLocation: true,
      ));
      // 开始定位
      locationPlugin.startLocation();
    } else {
      this.hasPermission = false;
    }

    // 永久拒绝不再询问
    if (statuses[Permission.location] == PermissionStatus.permanentlyDenied &&
        context != null) {
      showDialog(
        context: context,
        builder: (BuildContext context) {
          return AlertDialog(
            title: Text('提示'),
            content: Text('你似乎没有授予定位权限，是否前往设置？'),
            actions: <Widget>[
              TextButton(
                child: Text('前往'),
                onPressed: () {
                  openAppSettings();
                  Navigator.pop(context);
                },
              ),
            ],
          );
        },
      );
    }

    return this.hasPermission;
  }

  // 获取附近地点
  Future<List<LocationPoi>> getAroundPois() async {
    this.aroundPois = await LocationApi.getAroundPois(
      longitude: this.longitude!,
      latitude: this.latitude!,
    );
    notifyListeners();
    return this.aroundPois;
  }

  // 搜索
  Future<List<LocationPoi>> search({
    String keywords = '',
    String types = '',
  }) async {
    this.searchPois = await LocationApi.search(
      keywords: keywords,
      city: this.city,
      types: types,
    );
    notifyListeners();
    return this.searchPois;
  }
}
